package com.aggregate.pay.saobei.support;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.aggregate.pay.saobei.bean.AbstractData;
import com.aggregate.pay.saobei.bean.AbstractResult;
import com.aggregate.pay.saobei.support.utils.JSON;

/**
 * 接口API操作类抽象类
 * @author Moyq5
 * @date 2018年6月27日
 * @param <D>
 * @param <R>
 */
public abstract class AbstractClient<D extends AbstractData, R extends AbstractResult> implements Client<D, R> {

	private static Logger log = LoggerFactory.getLogger(AbstractClient.class);
	
	private Merch merch;
	
	public AbstractClient(Merch merch) {
		this.merch = merch;
	}
	
	@Override
	public R execute(D data) {
		R r = null;
		try {
			data.setMerchantNo(merch.merchantNo());
			data.setTerminalId(merch.terminalId());
			data.setKeySign(sign(data));
			
			String reqBody = JSON.toJson(data);
			log.debug("请求参数：{}", reqBody);
	
			HttpClient client = Factory.getHttpClient();
			String resBody = client.post(getApiPath(), reqBody);
			log.debug("响应参数：{}", resBody);
			
			r = JSON.toObject(resBody, getResultClass());
	
			if (r.getReturnCode().equals("01")) {
				String sign = sign(r);
				if (!sign.equalsIgnoreCase(r.getKeySign())) {
					log.warn("验签失败：源值[{}]!=实际值[{}]", data.getKeySign(), sign);
					throw new Exception("验签失败");
				}
				log.debug("签名验证通过");
			}
		} catch (Exception e) {
			log.error("接口调用失败", e);
			try {
				r = getResultClass().newInstance();
			} catch (Exception e1) {
				e1.printStackTrace();
			}
			r.setReturnCode("99");
			r.setReturnMsg(e.getMessage());
		}
		return r;
	}
	
	protected abstract Class<R> getResultClass();
	
	protected abstract String getApiPath();
	
	protected abstract String sign(D data);
	
	protected abstract String sign(R result);
	
}
